package com.fy56.platform.logistics.restful.api.utils.weChat;

import com.fy56.platform.logistics.restful.api.utils.StringToConversionUtil;
import com.fy56.platform.logistics.utils.BeanTransitionShopUtil;
import com.fy56.platform.logistics.utils.HttpClientUtils;
import com.fy56.platform.logistics.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * [接入工具类]微信-小程序
 */
public class WeChatAppletUtil {

	private static Logger log = LoggerFactory.getLogger(WeChatAppletUtil.class);
	
	/*----------------------------------------------------------------------------------------------------*/

	/**
	 * [获取]微信access_token
	 * @param appid 小程序 appId
	 * @param secret 小程序 secret
	 * @return
	 * @throws Exception
	 */
	public static String getAccessToken(String appid, String secret) throws Exception {
		String action = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
		String json = HttpClientUtils.get(action, null);
		Map<String, Object> map = BeanTransitionShopUtil.jsonToMap(json);
		return map.get("access_token") == null ? null : map.get("access_token").toString();
	}

	/*----------------------------------------------------------------------------------------------------*/

	/**
	 * [调用微信接口]登录凭证校验
	 * @param appid 小程序 appId
	 * @param secret 小程序 secret
	 * @param code (必填)登录时获取的 code
	 */
	public static Map<String, Object> getCredential(String appid, String secret, String code) throws Exception {
		// [获取]登录凭证校验请求路径
		String action = StringToConversionUtil.StrFormat("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code",
				new Object[]{appid, secret, code});
		String json = HttpClientUtils.get(action, null);
		
    	Map<String, Object> retModel = BeanTransitionShopUtil.jsonToMap(json);
    	if(StringToConversionUtil.isNotNull(retModel.get("openid"))){
			log.info("登录凭证校验成功！");
		}else{
			log.info("登录凭证校验失败！");
		}
		return retModel;
	}
	
	/**
	 * [调用微信接口]返回openid
	 * @param appid 小程序 appId
	 * @param secret 小程序 secret
	 * @param code (必填)登录时获取的 code
	 */
	public static String getOpenId(String appid, String secret, String code) throws Exception {
    	Map<String, Object> retModel = getCredential(appid, secret, code);
    	return retModel.get("openid") == null ? null : retModel.get("openid").toString();
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]返回unionid
	 * @param accessToken
	 * @param openid (必填)微信openid
	 */
	public static String getUnionId(String accessToken, String openid) throws Exception {
		// [获取]登录凭证校验请求路径
		String action = StringToConversionUtil.StrFormat("https://api.weixin.qq.com/wxa/getpaidunionid?access_token={0}&openid={1}",
				new Object[]{accessToken, openid});
		String json = HttpClientUtils.get(action, null);
    	Map<String, Object> retModel = BeanTransitionShopUtil.jsonToMap(json);
    	if("0".equals(retModel.get("errcode").toString())){
			log.info("返回unionid成功！");
		}else{
			log.info("返回unionid失败！"+retModel.get("errmsg").toString());
		}
    	return retModel.get("unionid") == null ? null : retModel.get("unionid").toString();
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]模板消息(服务通知消息)
	 * @param accessToken
	 * @param openid (必填)接收者[用户]的 openid
	 * @param templateId (必填)模板消息的id
	 * @param page (选填)模板卡片_跳转页面{仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转}
	 * @param formId (必填)表单提交场景下，为 submit事件带上的 formId；支付场景下，为本次支付的 prepay_id
	 * @param data (选填)模板内容{不填则下发空模板}
	 * @param emphasisKeyword (选填)模板需要放大的关键词{不填则默认无放大}
	 */
	public static Map<String, Object> getTemplateMessage(String accessToken, String openid, String templateId, String page,
			String formId, Map<String, Object> data, String emphasisKeyword){
		log.info("微信小程序-模板消息_开始推送");
		// 推送消息
		Map<String, Object> retModel = new LinkedHashMap<>();
		// [获取]推送消息请求路径
		String action = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + accessToken;
		
		Map<String, Object> params = new LinkedHashMap<>();
		params.put("touser", openid);//接收者（用户）的 openid
		params.put("template_id", templateId);//模板消息的id
		if(StringToConversionUtil.isNotNull(page)){
			params.put("page", page);//模板卡片_跳转页面
		}
		params.put("form_id", formId);
		if(StringToConversionUtil.isNotNull(data)){
			Map<String, Object> dataMap = new LinkedHashMap<>();
			for (String dataKey : data.keySet()) {
				Map<String, Object> valueMap = new LinkedHashMap<>();
				valueMap.put("value", data.get(dataKey));
				dataMap.put(dataKey, valueMap);
			}
			params.put("data", dataMap);//模板内容
		}
		if(StringToConversionUtil.isNotNull(emphasisKeyword)){
			params.put("emphasis_keyword", emphasisKeyword.trim()+".DATA");//模板需要放大的关键词
		}
		
		try {
			String c = BeanTransitionShopUtil.ots(params);
			log.info("### ===>>>\t传入json：" + c);
			String json = HttpClientUtils.postParameters(action, c);
			log.info("\n### ===>>>\t返回json：" + json);
			retModel = BeanTransitionShopUtil.jsonToMap(json);
			if("0".equals(retModel.get("errcode").toString())){
				log.info("微信小程序-模板消息_推送成功！");
			}else{
				log.info("微信小程序-模板消息_推送失败！"+retModel.get("errmsg").toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (ExecutionException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		}
		log.info("微信小程序-模板消息_结束推送");
		return retModel;
	}
	
	/*----------------------------------------------------------------------------------------------------*/
	
	/**
	 * [调用微信接口]客服消息
	 * @param accessToken
	 * @param msgType (必填)客服消息类型
	 * @param args (必填)参数
	 */
	public static Map<String, Object> getCustomerServiceMessage(String accessToken, WeChatEnum.CustomerServiceMessage_MsgType msgType, Object[] args){
		log.info("微信小程序-客服消息_开始推送");
		// 推送消息
		Map<String, Object> retModel = new LinkedHashMap<>();
		// [获取]推送消息请求路径
		String action = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
		
		Map<String, Object> params = msgType.getMap(args);
		try {
			String c = BeanTransitionShopUtil.ots(params);
			log.info("### ===>>>\t传入json：" + c);
			String json = HttpClientUtils.postParameters(action, c);
			log.info("\n### ===>>>\t返回json：" + json);
			retModel = BeanTransitionShopUtil.jsonToMap(json);
			if("0".equals(retModel.get("errcode").toString())){
				log.info("微信小程序-客服消息_推送成功！");
			}else{
				log.info("微信小程序-客服消息_推送失败！"+retModel.get("errmsg").toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (ExecutionException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		}
		log.info("微信小程序-客服消息_结束推送");
		return retModel;
	}

	/*----------------------------------------------------------------------------------------------------*/

	/**
	 * [调用微信接口]订阅消息
	 * @param accessToken
	 * @param openid (必填)接收者[用户]的 openid
	 * @param templateId (必填)模板消息的id
	 * @param page (选填)模板卡片_跳转页面{仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转}
	 * @param data (必填)模板内容
	 * @param miniprogramState (选填)跳转小程序类型{developer(开发版)/trial(体验版)/formal(正式版)},默认为正式版
	 * @param lang (选填)进入小程序查看”的语言类型{zh_CN(简体中文)/en_US(英文)/zh_HK(繁体中文)/zh_TW(繁体中文)},默认为zh_CN
	 */
	public static Map<String, Object> getSubscribeMessage(String accessToken, String openid, String templateId, String page,
			Map<String, Object> data, WeChatEnum.SubscribeMessage_MiniprogramState miniprogramState, WeChatEnum.SubscribeMessage_Lang lang){
		log.info("微信小程序-订阅消息_开始推送");
		// 推送消息
		Map<String, Object> retModel = new LinkedHashMap<>();
		// [获取]推送消息请求路径
		String action = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;

		Map<String, Object> params = new LinkedHashMap<>();
		params.put("touser", openid);//接收者（用户）的 openid
		params.put("template_id", templateId);//模板消息的id
		if(StringToConversionUtil.isNotNull(page)){
			params.put("page", page);//模板卡片_跳转页面
		}
		Map<String, Object> dataMap = new LinkedHashMap<>();
		for (String dataKey : data.keySet()) {
			Map<String, Object> valueMap = new LinkedHashMap<>();
			valueMap.put("value", data.get(dataKey));
			dataMap.put(dataKey, valueMap);
		}
		params.put("data", dataMap);//模板内容
		if(StringToConversionUtil.isNotNull(miniprogramState)){
			params.put("miniprogram_state", miniprogramState);//跳转小程序类型
		}

		try {
			String c = BeanTransitionShopUtil.ots(params);
			log.info("### ===>>>\t传入json：" + c);
			String json = HttpClientUtils.postParameters(action, c);
			log.info("\n### ===>>>\t返回json：" + json);
			retModel = BeanTransitionShopUtil.jsonToMap(json);
			if("0".equals(retModel.get("errcode").toString())){
				log.info("微信小程序-订阅消息_推送成功！");
			}else{
				log.info("微信小程序-订阅消息_推送失败！errcode:"+retModel.get("errcode").toString()+"\t"+retModel.get("errmsg").toString());
			}
		} catch (IOException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (ExecutionException e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("https request error:{}", e);
		}
		log.info("微信小程序-订阅消息_结束推送");
		return retModel;
	}



}
